#include "layout.h"

namespace Log4Qt
{

Layout::Layout(const QString &pattern)
{
    this->pattern = pattern;
    parse();
}

void Layout::parse()
{
    QString lacked = "";
    formatter = pattern;

    // %d %d{yyyy-MM-dd HH:mm:ss.zzz}
    QRegExp regex_d(R"(%d(\{(.*)\}){0,1})");
    if (regex_d.indexIn(formatter) >= 0)
    {
        int capCount = regex_d.captureCount();
        QString before = regex_d.cap();
        formatter = formatter.replace(before, "%1");
        dateTimeFlag = true;
        dateTimeFormat = DEFAULT_DATETIME_FORMAT;
    }
    else
    {
        dateTimeFlag = false;
        dateTimeFormat = "";
        lacked.append("%1");
    }

    // %c %12c
    QRegExp regex_c(R"(%(\d){0,2}c)");
    if (regex_c.indexIn(formatter) >= 0)
    {
        int capCount = regex_c.captureCount();
        QString before = regex_c.cap();
        formatter = formatter.replace(before, "%2");
        loggerNameFlag = true;
        loggerNameLength = 12;
    }
    else
    {
        loggerNameFlag = false;
        loggerNameLength = 0;
        lacked.append("%2");
    }

    // %F %16F
    QRegExp regex_F(R"(%(\d){0,2}F)");
    if (regex_F.indexIn(formatter) >= 0)
    {
        int capCount = regex_F.captureCount();
        QString before = regex_F.cap();
        formatter = formatter.replace(before, "%3");
        fileNameFlag = true;
        fileNameLength = 16;
    }
    else
    {
        fileNameFlag = false;
        fileNameLength = 0;
        lacked.append("%3");
    }

    // %l
    if (formatter.indexOf("%l") >= 0)
    {
        formatter = formatter.replace("%l", "%4");
        fileLineFlag = true;
        fileLineLength = 4;
    }
    else
    {
        fileLineFlag = false;
        fileLineLength = 0;
        lacked.append("%4");
    }

    // %p
    if (formatter.indexOf("%p") >= 0)
    {
        formatter = formatter.replace("%p", "%5");
        prioriryFlag = true;
        prioriryLength = 5;
    }
    else
    {
        prioriryFlag = false;
        prioriryLength = 0;
        lacked.append("%5");
    }

    // %m
    if (formatter.indexOf("%m") >= 0)
    {
        formatter = formatter.replace("%m", "%6");
        messageFlag = true;
    }
    else
    {
        messageFlag = false;
        lacked.append("%6");
    }

    // %%
    formatter.replace("%%", "%");
    formatter.append(lacked);
}

QString Layout::format(const QString &loggerName, const char *fileName,
                       int fileLine, const QString &level, const QString &msg)
{
    QString d, c, F, l, p, m;

    if (dateTimeFlag)
    {
        QDateTime dt = QDateTime::currentDateTime();
        d = dt.toString(dateTimeFormat);
    }

    if (loggerNameFlag)
    {
        c = loggerName;
        if (c.length() > loggerNameLength)
        {
            c = loggerName.left(loggerNameLength - 6)
                    + "..."
                    + loggerName.right(3);
        }
    }

    if (fileNameFlag)
    {
        F = fileName;
        if (F.length() > fileNameLength)
        {
            QString qfn(fileName);
            F = qfn.left(3)
                    + "..."
                    + qfn.right(fileNameLength - 6);
        }
    }

    if (fileLineFlag)
    {
        l = QString::number(fileLine);
    }

    if (prioriryFlag)
    {
        p = level;
    }

    if (messageFlag)
    {
        m = msg;
    }

    QString formatted = QString(formatter)
            .arg(d)
            .arg(c, loggerNameLength)
            .arg(F, fileNameLength)
            .arg(l, -fileLineLength)
            .arg(p, prioriryLength)
            .arg(m);

    return formatted;
}

}
